package org.chickymate.server.controller.command.dao.jdo;

import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import org.chickymate.server.controller.command.dao.CommentDao;
import org.chickymate.server.model.Comment;
import org.chickymate.server.model.Host;
import org.chickymate.server.model.Image;
import org.chickymate.server.model.Url;

public class JDOCommentDao extends AbstractJDODao implements CommentDao {

	private static final int PAGE_SIZE = 25;
	
	@Override
	public void addComment(String url, String text) {
		PersistenceManager pm = getPM();
		Comment comment = new Comment(url, text);
		pm.makePersistent(comment);
		updateTables(pm, comment, 1);
		pm.close();
	}
	
	@Override
	public List<Comment> getComments(String url) {
		PersistenceManager pm = getPM();
		Query query = pm.newQuery(Comment.class);
	    query.setFilter("url == urlParam");
	    query.setOrdering("votes desc");
	    query.declareParameters("String urlParam");
	    List<Comment> result = (List<Comment>) query.execute(url);
	    query.closeAll();
	    return result;
	}
	
	@Override
	public void vote(long id, int vote) {
		PersistenceManager pm = getPM();
		Comment comment = getComment(pm, id);
		comment.addVote(vote);
		updateTables(pm, comment, vote);
		pm.close();
	}
	
	@Override
	public List<Host> getPopularHosts() {
		PersistenceManager pm = getPM();
		Query query = pm.newQuery(Host.class);
	    query.setOrdering("votes desc");
	    query.setRange(0, PAGE_SIZE);
	    List<Host> result = (List<Host>) query.execute();
	    query.closeAll();
	    return result;	
	}

	@Override
	public List<Url> getPopularUrls() {
		PersistenceManager pm = getPM();
		Query query = pm.newQuery(Url.class);
		query.setOrdering("votes desc");
		query.setRange(0, PAGE_SIZE);
		List<Url> result = (List<Url>) query.execute();
		query.closeAll();
		return result;	
	}
	
	@Override
	public List<Comment> getRecentComments() {
		return getOrderedComments("createdDate desc");	
	}

	@Override
	public List<Comment> getPopularComments() {
		return getOrderedComments("votes desc");	
	}
	
	@Override
	public List<Image> getImagesUrls() {
		PersistenceManager pm = getPM();
		Query query = pm.newQuery(Image.class);
		query.setOrdering("votes desc");
		query.setRange(0, PAGE_SIZE);
		List<Image> result = (List<Image>) query.execute();
		query.closeAll();
		return result;	
	}
	
	private List<Comment> getOrderedComments(String ordering) {
		PersistenceManager pm = getPM();
		Query query = pm.newQuery(Comment.class);
		query.setOrdering(ordering);
		query.setRange(0, PAGE_SIZE);
		List<Comment> result = (List<Comment>) query.execute();
		query.closeAll();
		return result;	
	}
	
	private void updateTables(PersistenceManager pm, Comment comment, int vote) {
		updateHost(pm, comment.getHost(), vote);
		updateUrl(pm, comment.getUrl(), vote);
		if(isImage(comment.getPath())) {
			updateImage(pm, comment.getUrl() , vote);			
		}
	}

	private void updateHost(PersistenceManager pm, String host, int vote) {
		Host hostToUpdate = getHost(pm, host);
		if(hostToUpdate == null) {
			Host newHost = new Host();
			newHost.setHost(host);
			newHost.addVote(vote);
			pm.makePersistent(newHost);
		} else {
			hostToUpdate.addVote(vote);
		}
	}
	
	private void updateUrl(PersistenceManager pm, String url, int vote) {
		Url urlToUpdate = getUrl(pm, url);
		if(urlToUpdate == null) {
			Url newUrl = new Url();
			newUrl.setUrl(url);
			newUrl.addVote(vote);
			pm.makePersistent(newUrl);
		} else {
			urlToUpdate.addVote(vote);
		}
	}
	
	private void updateImage(PersistenceManager pm, String url, int vote) {
		Image toUpdate = getImage(pm, url);
		if(toUpdate == null) {
			Image newImage = new Image();
			newImage.setImageUrl(url);
			newImage.addVote(vote);
			pm.makePersistent(newImage);
		} else {
			toUpdate.addVote(vote);
		}
	}

	private Image getImage(PersistenceManager pm, String url) {
		try {
			return (Image)pm.getObjectById(Image.class, url);
		} catch (Exception e) {
			return null;
		}
	}
	
	private Host getHost(PersistenceManager pm, String host) {
		try {
			return (Host)pm.getObjectById(Host.class, host);
		} catch (Exception e) {
			return null;
		}
	}
	
	private Url getUrl(PersistenceManager pm, String url) {
		try {
			return (Url)pm.getObjectById(Url.class, url);
		} catch (Exception e) {
			return null;
		}
	}
	
	private Comment getComment(PersistenceManager pm, long id) {
		return (Comment)pm.getObjectById(Comment.class, new Long(id));
	}
	
	private boolean isImage(String path) {
		String pathLowerCase = path.toLowerCase();
		if(path != null && path.length() > 3) {
			if(pathLowerCase.endsWith(".jpeg") 
					|| pathLowerCase.endsWith(".png")
					|| pathLowerCase.endsWith(".jpg")
					|| pathLowerCase.endsWith(".gif")
					|| pathLowerCase.endsWith(".bmp")){
				return true;
			}
		}
		return false;
	}
	
}
